home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-MIPS / SEMAPHOR.{2G < prev    next >
Text File  |  1999-09-17  |  2KB  |  89 lines

  1. /*
  2.  * SMP- and interrupt-safe semaphores..
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * (C) Copyright 1996  Linus Torvalds, Ralf Baechle
  9.  */
  10. #ifndef __ASM_MIPS_SEMAPHORE_H
  11. #define __ASM_MIPS_SEMAPHORE_H
  12.  
  13. #include <asm/system.h>
  14. #include <asm/atomic.h>
  15. #include <asm/spinlock.h>
  16.  
  17. struct semaphore {
  18.     atomic_t count;
  19.     atomic_t waking;
  20.     struct wait_queue * wait;
  21. };
  22.  
  23. #define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
  24. #define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
  25.  
  26. extern void __down(struct semaphore * sem);
  27. extern int  __down_interruptible(struct semaphore * sem);
  28. extern void __up(struct semaphore * sem);
  29.  
  30. extern spinlock_t semaphore_wake_lock;
  31.  
  32. #define sema_init(sem, val)    atomic_set(&((sem)->count), val)
  33.  
  34. /*
  35.  * These two _must_ execute atomically wrt each other.
  36.  *
  37.  * This is trivially done with load_locked/store_cond,
  38.  * which we have.  Let the rest of the losers suck eggs.
  39.  */
  40.  
  41. static inline void wake_one_more(struct semaphore * sem)
  42. {
  43.     atomic_inc(&sem->waking);
  44. }
  45.  
  46. static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk)
  47. {
  48.     int ret, tmp;
  49.  
  50.     __asm__ __volatile__(
  51.     "1:\tll\t%1,%2\n"
  52.     "blez\t%1,2f\n\t"
  53.     "subu\t%0,%1,1\n\t"
  54.     "sc\t%0,%2\n\t"
  55.     "beqz\t%0,1b\n\t"
  56.     "2:"
  57.     ".text"
  58.     : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
  59.     : "0"(0));
  60.  
  61.     return ret;
  62. }
  63.  
  64. extern inline void down(struct semaphore * sem)
  65. {
  66.     if (atomic_dec_return(&sem->count) < 0)
  67.         __down(sem);
  68. }
  69.  
  70. extern inline int down_interruptible(struct semaphore * sem)
  71. {
  72.     int ret = 0;
  73.     if (atomic_dec_return(&sem->count) < 0)
  74.         ret = __down_interruptible(sem);
  75.     return ret;
  76. }
  77.  
  78. /*
  79.  * Note! This is subtle. We jump to wake people up only if
  80.  * the semaphore was negative (== somebody was waiting on it).
  81.  */
  82. extern inline void up(struct semaphore * sem)
  83. {
  84.     if (atomic_inc_return(&sem->count) <= 0)
  85.         __up(sem);
  86. }
  87.  
  88. #endif /* __ASM_MIPS_SEMAPHORE_H */
  89.